package com.xxg.renrenorder.component;

import com.xxg.renrencommon.domain.bean.CarryProductInfo;
import com.xxg.renrencommon.domain.dao.RenrenShopGoods;
import com.xxg.renrencommon.domain.dao.RenrenShopGoodsOption;
import com.xxg.renrencommon.exception.OrderManagerException;
import com.xxg.renrencommon.exception.exceptionenum.OrderExceptionCodeCodeEnum;
import com.xxg.renrenorder.dao.CarryProductInfoDao;
import com.xxg.renrenorder.dao.RenrenShopGoodsDao;
import com.xxg.renrenorder.dao.RenrenShopGoodsOptionDao;
import com.xxg.renrenorder.dao.bean.ProductInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 类说明
 *
 * @author szj
 * @date 2021/12/14
 */
@Component
@Slf4j
public class ProductStockComponentImpl implements ProductStockComponent{
    @Resource
    private RenrenShopGoodsOptionDao renrenShopGoodsOptionDao;
    @Resource
    private RenrenShopGoodsDao renrenShopGoodsDao;
    @Resource
    private CarryProductInfoDao carryProductInfoDao;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateStockAndSales(List<ProductInfo> productInfoList) throws OrderManagerException{
        for (ProductInfo productInfo : productInfoList) {
            updateStockAndSalesOne(productInfo);
        }

    }

    public void updateStockAndSalesOne(ProductInfo productInfo) throws OrderManagerException {
        RenrenShopGoods renrenShopGoods = renrenShopGoodsDao.selectByPrimaryKey(productInfo.getSpuId());
        if (productInfo.getSkuId().equals(productInfo.getSpuId())) {
            if (renrenShopGoods.getStock() < productInfo.getNumber()) {
                throw new OrderManagerException(productInfo.getSkuName() + "_" + OrderExceptionCodeCodeEnum.GOODS_STOCK_NOT_ENOUGH.getName(), OrderExceptionCodeCodeEnum.GOODS_STOCK_NOT_ENOUGH.getCode());
            }
            int newStock = renrenShopGoods.getStock() - productInfo.getNumber();
            int newSales = renrenShopGoods.getSales() + productInfo.getNumber();
            renrenShopGoodsDao.updateStockById(newStock, newSales, renrenShopGoods.getId());
        }else {
            RenrenShopGoodsOption renrenShopGoodsOption = renrenShopGoodsOptionDao.selectByPrimaryKey(productInfo.getSkuId());
            if (renrenShopGoodsOption.getStock() < productInfo.getNumber()) {
                throw new OrderManagerException(productInfo.getSkuName() + "_" + OrderExceptionCodeCodeEnum.GOODS_STOCK_NOT_ENOUGH.getName(), OrderExceptionCodeCodeEnum.GOODS_STOCK_NOT_ENOUGH.getCode());
            }
            int newSpuStock = renrenShopGoods.getStock() - productInfo.getNumber();
            int newSpuSales = renrenShopGoods.getSales() + productInfo.getNumber();
            int newSkuStock = renrenShopGoodsOption.getStock() - productInfo.getNumber();
            int newSkuSales = renrenShopGoodsOption.getSales() + productInfo.getNumber();
            renrenShopGoodsDao.updateStockById(newSpuStock, newSpuSales, renrenShopGoods.getId());
            renrenShopGoodsOptionDao.updateStockById(newSkuStock, newSkuSales, renrenShopGoodsOption.getId());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void rollBackStockAndSales(List<ProductInfo> productInfoList) {
        for (ProductInfo productInfo : productInfoList) {
            rollBackStockAndSalesOne(productInfo);
        }
    }

    @Override
    public void updateCarryProductStockAndSales(List<Integer> goodsIds) {
        List<RenrenShopGoodsOption> renrenShopGoodsOptions = renrenShopGoodsOptionDao.selectByGoodsIds(goodsIds);
        List<RenrenShopGoods> renrenShopGoodsList = renrenShopGoodsDao.selectByIds(goodsIds);
        Map<Integer, List<RenrenShopGoodsOption>> listMap = renrenShopGoodsOptions.stream().collect(Collectors.groupingBy(RenrenShopGoodsOption::getGoodsId));
        Map<Integer, RenrenShopGoods> goodsMap = renrenShopGoodsList.stream().collect(Collectors.toMap(RenrenShopGoods::getId, renrenShopGoods -> renrenShopGoods));
        for (int i = 0; i < goodsIds.size(); i++) {
            RenrenShopGoods renrenShopGoods = goodsMap.get(goodsIds.get(i));
            if (renrenShopGoods == null) {
                continue;
            }
            List<CarryProductInfo> carryProductInfos = carryProductInfoDao.findBySpuId(goodsIds.get(i));
            if (carryProductInfos == null || carryProductInfos.size() <= 0) {
                continue;
            }
            HashMap<Integer, List<Integer>> map = new HashMap<>(16);
            for (CarryProductInfo carryProductInfo : carryProductInfos) {
                Map<String, Integer> skuIdMap = carryProductInfo.getSkuIdMap();
                if (skuIdMap != null) {
                    skuIdMap.forEach((k, v) -> {
                        if (map.containsKey(v)) {
                            map.get(v).add(Integer.parseInt(k));
                        }else {
                            ArrayList<Integer> list = new ArrayList<>();
                            list.add(Integer.parseInt(k));
                            map.put( v, list);
                        }
                    });
                }
            }
            List<Integer> collect = carryProductInfos.stream().map(CarryProductInfo::getCarrySpuId).collect(Collectors.toList());
            renrenShopGoodsDao.updateStockByIds(collect, renrenShopGoods.getStock(), renrenShopGoods.getSales());
            List<RenrenShopGoodsOption> renrenShopGoodsOptions1 = listMap.get(goodsIds.get(i));
            if (renrenShopGoodsOptions1 == null || renrenShopGoodsOptions1.size()<= 0) {
                continue;
            }
            for (RenrenShopGoodsOption renrenShopGoodsOption : renrenShopGoodsOptions1) {
                // 找出所有映射的sku
                List<Integer> list = map.get(renrenShopGoodsOption.getId());
                renrenShopGoodsOptionDao.updateStockByIds(list, renrenShopGoodsOption.getStock(), renrenShopGoodsOption.getSales());
            }
        }
    }

    public void rollBackStockAndSalesOne(ProductInfo productInfo) {
        RenrenShopGoods renrenShopGoods = renrenShopGoodsDao.selectByPrimaryKey(productInfo.getSpuId());
        if (productInfo.getSkuId().equals(productInfo.getSpuId())) {
            int newStock = renrenShopGoods.getStock() + productInfo.getNumber();
            int newSales = renrenShopGoods.getSales() - productInfo.getNumber();
            renrenShopGoodsDao.updateStockById(newStock, newSales, renrenShopGoods.getId());
        }else {
            RenrenShopGoodsOption renrenShopGoodsOption = renrenShopGoodsOptionDao.selectByPrimaryKey(productInfo.getSkuId());
            int newSpuStock = renrenShopGoods.getStock() + productInfo.getNumber();
            int newSpuSales = renrenShopGoods.getSales() - productInfo.getNumber();
            int newSkuStock = renrenShopGoodsOption.getStock() + productInfo.getNumber();
            int newSkuSales = renrenShopGoodsOption.getSales() - productInfo.getNumber();
            renrenShopGoodsDao.updateStockById(newSpuStock, newSpuSales, renrenShopGoods.getId());
            renrenShopGoodsOptionDao.updateStockById(newSkuStock, newSkuSales, renrenShopGoodsOption.getId());
        }
    }
}
